package com.common.atom.seal.util;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * description: 印章透明化处理工具 <br>
 * date: 2023/4/13  <br>
 * author: zss <br>
 * version: 1.0.0 <br>
 */
public class LimpidUtils {


    /**
     * 对图片中的 黑色或白色进行透明化处理
     *
     * @param input  输入流
     * @param color  要修改的颜色 1红色 2 绿色 3 蓝色 4 黑色
     * @param cutout 抠图值 0 - 255，值越大处理后扣除的白边值越大
     * @return 透明化处理后的图片
     */
    public static byte[] transferAlpha(InputStream input, String color, int cutout) throws IOException {
        BufferedImage bufferedImage = null;
        int sWidth = 0, sHeight = 0;
        if (ColorUtils.BLACK_MODE.equals(color)) {
            BufferedImage orginalImage = ImageIO.read(input);
            sWidth = orginalImage.getWidth();
            sHeight = orginalImage.getHeight();
            bufferedImage = new BufferedImage(
                    sWidth, sHeight,
                    BufferedImage.TYPE_BYTE_BINARY);
            Graphics2D graphics = bufferedImage.createGraphics();
            graphics.drawImage(orginalImage, 0, 0, null);

        } else {
            ImageIcon imageIcon = new ImageIcon(ImageIO.read(input));
            sWidth = imageIcon.getIconWidth();
            sHeight = imageIcon.getIconHeight();
            bufferedImage = new BufferedImage(
                    imageIcon.getIconWidth(), imageIcon.getIconHeight(),
                    BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
            g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
        }
        int x1 = -1, y1 = -1, x2 = bufferedImage.getMinX(), y2 = bufferedImage.getMinY();
        for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
            for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
                int rgb = bufferedImage.getRGB(j2, j1);
                boolean isWhite = checkColorIsWhite(rgb, cutout);
                if (isWhite) {
                    rgb = (1 << 24) | (rgb & 0x00ffffff);
                } else {
                    if (rgb != 0) {
                        if (x1 == -1) {
                            x1 = j2;
                        } else {
                            if (j2 < x1) {
                                x1 = j2;
                            }
                        }
                        if (x2 < j2) {
                            x2 = j2;
                        }

                        if (y1 == -1) {
                            y1 = j1;
                        } else {
                            if (j1 < y1) {
                                y1 = j1;
                            }
                        }
                        if (y2 < j1) {
                            y2 = j1;
                        }
                        rgb = changeColor(rgb, 255, color);
                    }
                }

                bufferedImage.setRGB(j2, j1, rgb);
            }
        }

        int border = 2;
        if (x1 > border) {
            x1 -= border;
            x2 += border;
        }

        if (y1 > border) {
            y1 -= border;
            y2 += border;
        }
//检查长宽
        int nWidth = x2 - x1;
        int nHeight = y2 - y1;

        nWidth = (x1 + nWidth) > sWidth ? (sWidth - x1) : nWidth;
        nHeight = (y1 + nHeight) > sHeight ? (sHeight - y1) : nHeight;

        BufferedImage subImage = bufferedImage.getSubimage(x1, y1, nWidth, nHeight);

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(subImage, "png", output);

        return output.toByteArray();

    }

    /**
     * 印章透明化
     *
     * @param rgb   颜色值
     * @param alpha 要修改的透明度0 - 255
     * @param color 要修改的颜色 1红色 2 绿色 3 蓝色 4 黑色
     * @return 修改后的颜色值
     */
    private static int changeColor(int rgb, int alpha, String color) {
        int colorAlpha = 255;

        if (alpha < 0 || alpha > colorAlpha) {
            throw new RuntimeException("透明度值设置错误");
        }

        int r = (rgb & 0xff0000) >> 16;
        int g = (rgb & 0xff00) >> 8;
        int b = (rgb & 0xff);

        List<Integer> rgbArray = Arrays.asList(r, g, b);
        rgbArray.sort((x, y) -> x > y ? x : y);

        rgb = rgb & alpha << 24;
        if (color.equals("0")) {
            return rgb | r << 16 | g << 8 | b;
        } else if (ColorUtils.RED_MODE.equals(color)) {
            ///return rgb | 0xff << 16 | g << 8 | b;
            return rgb | 0xff << 16;
        } else if (ColorUtils.GREEN_MODE.equals(color)) {
            return rgb | r << 16 | 0xff << 8 | b;
        } else if (ColorUtils.BLUE_MODE.equals(color)) {
            return rgb | r << 16 | g << 8 | 0xff;
        } else if (ColorUtils.BLACK_MODE.equals(color)) {
            //int color1 = ColorUtil.getColor("#010101", alpha / 25.5).getRGB();

            rgb = rgb & 0xff000000;
            return rgb;
        } else if (color != null && color.startsWith("#")) {
            return ColorUtils.getColor(color, alpha / 25.5).getRGB();
        } else {
            return rgb | rgbArray.get(0) << 16 | rgbArray.get(1) << 8 | rgbArray.get(2);
        }
    }

    /**
     * 检查颜色是否为 白色
     *
     * @param rgb    颜色值
     * @param cutout 抠图值 0 - 255，值越大处理后白边越少
     * @return 检查结果
     */
    private static boolean checkColorIsWhite(int rgb, int cutout) {
        int r = (rgb & 0xff0000) >> 16;
        int g = (rgb & 0xff00) >> 8;
        int b = (rgb & 0xff);
        return ((255 - r) <= cutout) && ((255 - g) <= cutout) && ((255 - b) <= cutout);
    }

    public static boolean hasAlpha(byte[] imageData) {
        boolean hasAlpha = false;
        Image image = new ImageIcon(imageData).getImage();
        if (image instanceof BufferedImage) {
            BufferedImage bimage = (BufferedImage) image;
            hasAlpha = bimage.getColorModel().hasAlpha();
        } else {
            PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
            try {
                pg.grabPixels();
                ColorModel cm = pg.getColorModel();
                hasAlpha = cm.hasAlpha();
            } catch (InterruptedException e) {
            }
        }
        return hasAlpha;
    }

}
